package io.r2mo.test.common;

import io.r2mo.spring.junit5.AppBaseTestSupport;
import io.r2mo.test.common.domain.ProductCatEntity;
import io.r2mo.typed.common.Pagination;
import io.r2mo.typed.constant.DefaultConstantValue;
import io.r2mo.typed.json.JObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.Commit;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author lang : 2025-09-07
 */
@SpringBootTest(classes = TestCommonApplication.class)
@TestPropertySource("classpath:env-test.properties")
@Transactional
@Component
@Slf4j
public class DbCrudActTestCase extends AppBaseTestSupport<ProductCatEntity> {

    private ProductCatEntity executeInsert(final String filename) {
        final ProductCatEntity productCatEntity =
            this.inOne(filename, ProductCatEntity.class);
        return this.db().create(productCatEntity);
    }

    private List<ProductCatEntity> executeBatchInsert(final String filename) {
        final List<ProductCatEntity> productCatEntities =
            this.inMany(filename, ProductCatEntity.class);
        return this.db().create(productCatEntities);
    }

    @Test
    @Commit
    public void insertProduct() {
        final long countBefore = this.db().count().orElse(0L);
        final ProductCatEntity inserted = this.executeInsert("HFS/database/wait-insert.json");
        final ProductCatEntity removed = this.db().remove(inserted);
        Assertions.assertEquals(inserted, removed);
        final long countAfter = this.db().count().orElse(0L);
        Assertions.assertEquals(countBefore, countAfter);
    }

    @Test
    @Commit
    public void updateProduct() {
        final ProductCatEntity inserted = this.executeInsert("HFS/database/wait-update.json");
        inserted.setName("户外运动-01");
        inserted.setUpdatedBy(DefaultConstantValue.BY_TESTER);
        final ProductCatEntity updated = this.db().update(inserted);
        System.out.println(updated.dgInfo());

        final ProductCatEntity queried = this.db().findOne("code", "CAT004").orElse(null);
        final ProductCatEntity queried2 = this.db().findOne(updated.getId()).orElse(null);
        Assertions.assertNotNull(queried);
        Assertions.assertNotNull(queried2);
        Assertions.assertEquals(queried, queried2);
        Assertions.assertEquals(updated.getId(), queried.getId());
        Assertions.assertEquals("户外运动-01", queried.getName());

        final ProductCatEntity removed = this.db().remove(updated);
        Assertions.assertEquals(updated, removed);
    }

    @Test
    @Commit
    public void insertBatchProduct() {
        final List<ProductCatEntity> productCatEntities = this.executeBatchInsert("HFS/database/wait-inserts.json");

        final long countAfter = this.db().count().orElse(0L);
        Assertions.assertTrue(countAfter > 1);
        log.info("[ R2MO ] (1) insertBatchProduct / 批量插入数据完成，当前总数：{} ", countAfter);
        final List<ProductCatEntity> removed = this.db().remove(productCatEntities);
        Assertions.assertEquals(productCatEntities.size(), removed.size());
    }

    @Test
    @Commit
    public void searchProduct() {
        /*
         * 两条生成语句（语句生成上看是对的）
         *
         * 查询
         * SELECT id,name,type,description,icon,sort,amount_market,publish_at,parent_id,code,created_by,created_at,
         * updated_by,updated_at,is_enabled AS enabled,language,version,tenant_id,app_id,c_metadata FROM tk_product_cat
         * WHERE ((type = ?)) ORDER BY name DESC LIMIT ?,?
         * 记数
         * SELECT COUNT(*) AS total FROM tk_product_cat WHERE ((type = ?))
         */
        final JObject queryJ = this.fs().inJson("HFS/database/for-query.json");
        final Pagination<ProductCatEntity> paged = this.db().findPage(queryJ);
        System.out.println(paged.getCount());
    }

    @Test
    @Commit
    public void testMap() {
        final String appId = "98704911-d702-460a-b53c-5992d5680753";
        final String tenantId = "6a78273f-a9a4-4adf-8c89-1062609182ee";

        this.db().findManyIn("appId", List.of(appId, tenantId));

        final Map<String, Object> condition = Map.of(
            "appId", appId,
            "tenantId", appId
        );
        final List<ProductCatEntity> queried = this.db().findMany(condition);
        System.out.println(queried.size());
    }

    @Test
    @Commit
    public void testNullId() {

        final ProductCatEntity found = this.db().findOne("code", "CAT001").orElse(null);
        if (Objects.nonNull(found)) {
            System.out.println(found.dgInfo());
        }
    }
}
